///// Кнопка на D1 GPIO5
///// Диод Ерор на D2 GPIO4
///// Диод нормальное стостояние на D6 GPIO12
///// Сенсор импульсный D7 GPIO13
///// Реле подключено D5 GPIO14

#include "WiFiSettings.h"

#include <EEPROM.h> // Работа с памятью

///// Класс кнопка подключаем на на D1 GPIO5
#include "Button.h"
button butt(5,5); // Создаем экземпляр класса подключаем на на D1 GPIO5 с временем задержки длительного нажатия 5 сек
/////

///// Класс сенсор Подключаем сенсон к D7 GPIO13
#include "Sensor_Impulse.h"
impulsSensor sensorIm(13,100); // Создаем экземпляр класса подключаем сенсон к D7 GPIO13 и задержка в милисек
/////

///// Реле подключаем на на D5 GPIO12
#include "Rele.h"
releControl releContr(14,1); // Реле подключаем на на D5 GPIO14, 0 - нормально закрытый клапан 1 - номально открытый
////

/////Таймер на Миллис для ошибки
uint32_t timerFatall = 0;   // Переменная для хранения милис
int timerMaxFatall = 10000; // Время интервала подсчета воды 1000 = 1сек
/////

///// Переменная для выбора сенсора true - импульсный сенсор считает литры, false - сенсор потока 
bool choceSensor = true;
/////

///// Сенсор импульсный 
int impulseCount = 0;   // Счетчик импульсов
int impulseMax = 50;    // Максимальное значение импульсов для ошибки
/////

bool errorFatal = false; //Фатальная ошибка закрываем клапан

///// Диод ошибки D2 GPIO4
int ledError = 4;     //Подключаем диод к D2 GPIO4
/////

///// Диод нормальное стостояние на D6 GPIO12
int ledNorma = 12;     //Подключаем диод к D2 GPIO4
/////
void stenBy(bool error)
{
  if (error == true) // Опрос состояния
  {
    releContr.runRele(false); //Включаем реле
    digitalWrite(ledError, HIGH); // Включаем диод
    digitalWrite(ledNorma, LOW); // Включаем диод
  }else if (error == false)
  {
    releContr.runRele(true); //Включаем реле
    digitalWrite(ledError, LOW); // Включаем диод
    digitalWrite(ledNorma, HIGH); // Включаем диод
  }
}
void interview()
{
  EEPROM.get(0, errorFatal); // получаем запись об ошибке в памяти по 0 адресу 1 байт
  EEPROM.get(1, timerMaxFatall); // получаем запись об timerMaxFatall в памяти по 1 адресу инт зани мает 4 байта
  EEPROM.get(5, impulseMax); // получаем запись об impulseMax в памяти по 5 адресу инт зани мает 4 байта
  EEPROM.get(17, choceSensor); //Добавил/// получаем запись об choceSensor в памяти по 17 адресу bool зани мает 1 байта
}
void setup() 
{
  Serial.begin(115200);
  pinMode(ledError, OUTPUT);      // Подключаем Диод 
  pinMode(ledNorma, OUTPUT);      // Подключаем Диод 
  EEPROM.begin(100); // Выделяем объем памяти 100
  interview(); // Опрос состояния
  stenBy(errorFatal); // настройка сосотояния
  setupWIFI(timerMaxFatall, impulseMax); // Настройки вайфай
}
// Функция тригер фатальной ошибки
bool fatalError(bool error)
{
  if (error == true)
  {
    errorFatal = error;
    stenBy(error);
    EEPROM.put(0, errorFatal); // Записываем переменную в память
    EEPROM.commit(); // применить запись
  }
  else
  {
    errorFatal = error;
    impulseCount = 0;
    stenBy(error);
    EEPROM.put(0, errorFatal); // Сбрасываем переменную в памяти
    EEPROM.commit(); // применить запись
  }
  return error;
}

void loop() 
{
  // Проверка на фатальную ошибку если есть то не проверяем
  if (errorFatal == false)
  {
    //Добавил///
    if(choceSensor == true)
    {
    // Подсчет импульсов и задано время до фатальной ошибки
      if (sensorIm.pollingSensor())
      {
        impulseCount += 1;
        Serial.println("Количество импульсов = " + String(impulseCount));
      }
      // Таймер для фатальной ошибки
      if (((millis() - timerFatall) < timerMaxFatall) && impulseCount >= impulseMax)
      { 
        timerFatall = millis();
        fatalError(true);
      }
      else if (((millis() - timerFatall) > timerMaxFatall) && impulseCount < impulseMax)
      {
        timerFatall = millis();
        impulseCount = 0;
      }
    }
    // мы используем датчик потока то при появлении потока включаем таймер
    else 
    {
      if (sensorIm.potocSensor() == true) // под вопросом возможно надо новый клас сенсора если вода идет сенсор должен дать сигнал замыкания
      {
        if ((millis() - timerFatall) > timerMaxFatall)
        { 
          fatalError(true);
          timerFatall = millis();
        }
      }
      else
      {
        timerFatall = millis(); 
      } 
    }

  }
  //Сброс состояния
  switch (butt.Click())
  {
    case 1:
      Serial.println("Однокраное нажатие");
      Serial.println("Нажатие с кнопки: Сенсор переменный: " + String(sensorIm.pollingSensor()) + " Сенсор потоковый: " + String(sensorIm.potocSensor()) + " " + String(_timerMFatall) + " милисекунды" + "\n"+ String(_literLimit) + " Импульсов");
      break;
    case 2:
      // Сброс оштбки при длительном нажатии кнопки
      Serial.println("Длительное нажатие");
      fatalError(false);
      break;
  }
  //проверка на изменение настроек 
  if (_triger==true)
  {
    interview(); // Опрос состояния
    fatalError(false);
    _triger=false;
  }
  loopWIFI(); // Запускаем вай фай
}